package models

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"github.com/astaxie/beego/orm"
	"strconv"
	"time"
)

/**
 *  用户结构体
 */
type UserTable struct {
	Userid    int64  `orm:"column(userid);pk"` //设置主键
	Name      string // Username=> username
	Passwd    string // PassWd=> pass_wd
	Sex       string
	Logindate string
	Regtime   string // LoginTime=> login_time
	Status    int
	Headpic   string
}

/**
 *  MD5加密
 */
func GetMd5String(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	return hex.EncodeToString(h.Sum(nil))
}

/**
 *  用户注册
 */
func Register(name, sex, passwd, headimg string) (insertId int64, err error) {
	//密码的MD5 加密
	pwd := GetMd5String(passwd)
	timeNow := time.Now()
	regTime := timeNow.Format("2006-01-02 15:04:05")

	o := orm.NewOrm()
	reg := UserTable{Name: name, Passwd: pwd, Sex: sex, Regtime: regTime, Logindate: regTime, Headpic: headimg}
	id, err := o.Insert(&reg)
	fmt.Println(id)
	//return user
	return id, err
}

/**
 * 用户名查询一个用户
 */
func ReadByName(name string) (int64, error) {
	num, err := UserTableObj().Filter("Name", name).Count()
	if err != nil {
		log := UitlLog()
		log.Error("connect db err" + err.Error())
		return 0, err
	}
	return num, nil
}

/**
 * id查询一个用户
 */
func GetUserById(id int64) *UserTable {
	o := orm.NewOrm()
	userTable := new(UserTable)
	//var noteBook *NoteBook =  new(NoteBook)
	userTable.Userid = id
	err := o.Read(userTable)
	if err == orm.ErrNoRows {
		//fmt.Println("查询不到")
		log := UitlLog()
		log.Error("查询不到" + err.Error())
		return nil
	} else if err == orm.ErrMissPK {
		//fmt.Println("找不到主键")
		log := UitlLog()
		log.Error("找不到主键" + err.Error())
		return nil
	}
	return userTable
}

/**
 *  用户模糊查询
 */
func UserFuzzyQs(val string, offset, limit int) ([]UserTable, error) {
	var UserTable []UserTable
	cond := orm.NewCondition()
	qs := UserTableObj()
	id, err_ := strconv.Atoi(val)
	if err_ == nil {
		_, err1 := qs.Filter("Userid", id).All(&UserTable)
		if err1 != nil {
			log := UitlLog()
			log.Error("connect db err" + err1.Error())
			return nil, err1
		}
		return UserTable, nil
	}
	cond1 := cond.And("Name__icontains", val).Or("Sex__icontains", val)
	qs = qs.SetCond(cond1)
	// WHERE ... AND ... AND NOT ... OR ...
	_, err2 := qs.Offset(offset).Limit(limit).All(&UserTable)
	if err2 != nil {
		log := UitlLog()
		log.Error("connect db err" + err2.Error())
		return nil, err2
	}
	return UserTable, nil
}

/**
* 获取：糊查询数
 */
func UserFuzzyQsCount(val string) int64 {
	var UserTable []UserTable
	cond := orm.NewCondition()
	qs := UserTableObj()
	id, err_ := strconv.Atoi(val)
	if err_ == nil {
		_, err1 := qs.Filter("Userid", id).All(&UserTable)
		if err1 != nil {
			log := UitlLog()
			log.Error("connect db err" + err1.Error())
			return 0
		}
		return 1
	}
	cond1 := cond.And("Name__icontains", val).Or("Sex__icontains", val)
	qs = qs.SetCond(cond1)
	// WHERE ... AND ... AND NOT ... OR ...
	num, err2 := qs.Count()
	if err2 != nil {
		log := UitlLog()
		log.Error("connect db err" + err2.Error())
		return 0
	}
	return num
}

/**
 * 根据ID删除用户
 */
func DelUser(id int64) (int64, error) {

	o := orm.NewOrm()
	userTable := new(UserTable)
	userTable.Userid = id

	num, err := o.Delete(userTable)
	if err != nil {
		log := UitlLog()
		log.Error("connect db err" + err.Error())
		return 0, err
	}

	return num, nil
}

/**
 * 根据ID修改数据
 */
func UpUser(id, sta int64, name, sex, passwd, headimg string) *UserTable {
	o := orm.NewOrm()
	userTable := new(UserTable)
	//密码的MD5 加密
	pwd := GetMd5String(passwd)
	userTable.Userid = id
	if o.Read(userTable) == nil {
		userTable.Name = name
		userTable.Sex = sex
		userTable.Passwd = pwd
		userTable.Status = int(sta)
		userTable.Headpic = headimg

		//fmt.Println(noteBook.Username)
		if _, err := o.Update(userTable, "Name", "Passwd", "Sex", "Status", "Headpic"); err != nil {
			log := UitlLog()
			log.Error("connect db err" + err.Error())
			return nil
		}
	}

	//return user
	return userTable

}

/**
* 获取；用户列表
 */
func GetUserList(offset, limit int) ([]UserTable, error) {

	var UserTable []UserTable
	_, err := UserTableObj().Offset(offset).Limit(limit).All(&UserTable)
	if err != nil {
		log := UitlLog()
		log.Error("查询 err" + err.Error())
		return nil, err
	}
	return UserTable, nil
}

/**
* 获取：总数
 */
func GetUserCount() int64 {
	o := orm.NewOrm()
	userTable := new(UserTable)
	cnt, err := o.QueryTable(userTable).Count()
	if err != nil {
		log := UitlLog()
		log.Error("Not row found" + err.Error())
		return 0
	}

	return cnt
}

/**
*  用户验证
 */
func InUser(usname, passwd string) (*UserTable, error) {
	//密码的MD5 加密
	pwd := GetMd5String(passwd)
	/*
		//方法一
		noteBook := new(NoteBook)
		noteBook.Username = usname
		noteBook.Passwd = passwd

		err := o.Read(noteBook,"Username","Passwd")

		if err!=nil{
			fmt.Println("query error:"+err.Error())
			return err
		}
	*/
	//方法二
	var UserTable *UserTable = new(UserTable)
	o := orm.NewOrm()
	qs := o.QueryTable(UserTable)  // 返回 QuerySeter
	qs = qs.Filter("Name", usname) // WHERE id = 1
	qs = qs.Filter("Passwd", pwd)  // WHERE id = 1
	err1 := qs.One(UserTable)
	_, err2 := qs.All(UserTable)

	if err1 != nil {
		log := UitlLog()
		log.Error("Not row found" + err1.Error())
		return nil, err1
	}
	if err2 != nil {
		log := UitlLog()
		log.Error("connect db err" + err2.Error())
		return nil, err2
	}
	//if err == orm.ErrMultiRows {
	//	// 多条的时候报错
	//	fmt.Printf("Returned Multi Rows Not One"+err.Error())
	//	return err
	//}
	if err1 == orm.ErrNoRows {
		// 没有找到记录
		//fmt.Printf("Not row found" + err.Error())
		log := UitlLog()
		log.Error("Not row found" + err1.Error())
		return nil, err1
	} else {

		timeNow := time.Now()
		loginTime := timeNow.Format("2006-01-02 15:04:05")
		//fmt.Println("时间:"+loginTime)
		UserTable.Logindate = loginTime

		if _, err3 := o.Update(UserTable); err3 != nil {
			log := UitlLog()
			log.Error("数据更新 err" + err3.Error())
			return nil, err3

		}
	}
	// 成功
	return UserTable, nil
}

/**
 * /却换禁言状态status
 */
func EditStatus(id, stu int64) error {
	if stu == 0 {
		_, err := UserTableObj().Filter("Userid", id).Update(orm.Params{
			"Status": 1,
		})
		if err != nil {
			log := UitlLog()
			log.Error("connect db err" + err.Error())
			return err
		}
		return nil

	} else {
		_, err := UserTableObj().Filter("Userid", id).Update(orm.Params{
			"Status": 0,
		})
		if err != nil {
			log := UitlLog()
			log.Error("connect db err" + err.Error())
			return err
		}
	}
	return nil
}

/**
 * UserTable 表实例化
 */
func UserTableObj() orm.QuerySeter {
	return orm.NewOrm().QueryTable(new(UserTable))
}
